﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.Threading;
using Microsoft.Xna.Framework.Input;

namespace FrogEngine
{
	public class ScreenManager : GameEntityBase, ILogical, IRenderable, IHandlesAllInput
	{
		public ScreenManager(IEngine engine)
			: base(engine)
		{
			stateMachine = new ScreenManagerFSM();

			Services.Add(engine.GetService<GamePadInputService>());
			Services.Add(engine.GetService<KeyboardInputService>());
			Services.Add(engine.GetService<MouseInputService>());

			foreach (var service in Services)
				service.Subscribe(this);
		}

		public ScreenManager(IEngine engine, string fileName)
			: base(engine)
		{
			stateMachine = new ScreenManagerFSM(fileName);
		}

		public IList<IGameScreen> Screens
		{
			get { return stateMachine.GetAllStates.Select(a => a as IGameScreen).ToList(); }
		}

		public IGameScreen CurrentScreen
		{
			get { return stateMachine.CurrentState as IGameScreen; }
		}

		public void AddScreen(IGameScreen screen)
		{
			screen.ScreenManager = this;
			stateMachine.AddState(screen);
		}

		public void RemoveScreen(IGameScreen screen)
		{
			screen.ScreenManager = null;
			stateMachine.RemoveState(screen);
		}

		public void Transition(IGameScreen nextScreen)
		{
			stateMachine.Transition(nextScreen);
		}

		public void Update(GameTime gameTime)
		{
			stateMachine.Update(gameTime);
		}

		public void Render(GameTime gameTime)
		{
			stateMachine.Render(gameTime);
		}

		private ScreenManagerFSM stateMachine;

		public void HandleInput(GameTime gameTime, PlayerIndex index, KeyboardState currentState, KeyboardState previousState)
		{
			var current = this.CurrentScreen;
			if (current != null)
			{
				if (current.PlayerIndex.HasFlag(index))
					current.HandleInput(gameTime, index, currentState, previousState);
			}
		}

		public PlayerIndex PlayerIndex
		{
			get
			{
				return FrogEngine.PlayerIndex.One | FrogEngine.PlayerIndex.Two |
				  FrogEngine.PlayerIndex.Three | FrogEngine.PlayerIndex.Four;
			}
		}

		public void HandleInput(GameTime gameTime, MouseState currentState, MouseState prevState, float dx, float dy)
		{

		}

		public void HandleInput(GameTime gameTime, PlayerIndex index, GamePadState currentState, GamePadState previousState)
		{
			var current = this.CurrentScreen;
			if (current != null)
			{
				if (current.PlayerIndex.HasFlag(index))
					current.HandleInput(gameTime, index, currentState, previousState);
			}
		}
	}
}
